package com.lzj.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lzj.admin.pojo.Role;
import com.lzj.admin.mapper.RoleMapper;
import com.lzj.admin.pojo.RoleMenu;
import com.lzj.admin.query.RoleQuery;
import com.lzj.admin.service.IRoleMenuService;
import com.lzj.admin.service.IRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzj.admin.utils.AssertUtil;
import com.lzj.admin.utils.PageResultUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author luoyoumou
 * @date 2022-12-05
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    @Resource
    private IRoleMenuService roleMenuService;

    /**
     * 角色列表页查询
     * @param roleQuery
     * @return
     */
    @Override
    public Map<String, Object> roleList(RoleQuery roleQuery) {

        IPage<Role> page = new Page<Role>(roleQuery.getPage(), roleQuery.getLimit());
        QueryWrapper<Role> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_del",0);
        if(StringUtils.isNotBlank(roleQuery.getRoleName())){
            queryWrapper.like("name",roleQuery.getRoleName());
        }
        page = this.baseMapper.selectPage(page,queryWrapper);
        return PageResultUtil.getResult(page.getTotal(),page.getRecords());
    }

    /**
     * 角色信息添加
     * @param role
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void saveRole(Role role) {
        AssertUtil.isTrue(StringUtils.isBlank(role.getName()),"请输入角色名！");
        AssertUtil.isTrue(null != this.findRoleByRoleName(role.getName()), "角色名已存在！" );
        role.setIsDel(0);
        AssertUtil.isTrue(!(this.save(role)),"角色记录添加失败！");
    }

    /**
     * 根据角色名称，查询角色信息
     * @param roleName
     * @return
     */
    @Override
    public Role findRoleByRoleName(String roleName){
        return this.baseMapper.selectOne(new QueryWrapper<Role>().eq("is_del",0).eq("name",roleName));
    }

    /**
     * 更新角色信息
     * @param role
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void updateRole(Role role) {
        AssertUtil.isTrue(StringUtils.isBlank(role.getName()),"请输入角色名！");
        Role tempRole = this.findRoleByRoleName(role.getName());
        AssertUtil.isTrue(null != tempRole && !(tempRole.getId().equals(role.getId())), "角色名已存在！" );
        AssertUtil.isTrue(!(this.updateById(role)),"角色记录更新失败！");
    }

    /**
     * 删除角色信息
     * @param id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void deleteRole(Integer id) {
        AssertUtil.isTrue( null == id, "请选择待删除记录！");
        Role role = this.getById(id);
        AssertUtil.isTrue( null == role, "待删除记录不存在！");
        role.setIsDel(1);
        AssertUtil.isTrue(!(this.updateById(role)),"角色记录删除失败！");
    }

    /**
     * 获取角色列表
     * @param userId
     * @return
     */
    @Override
    public List<Map<String, Object>> queryAllRoles(Integer userId) {
        return this.baseMapper.queryAllRoles(userId);
    }

    /**
     * 角色权限添加操作
     * 1. 参数校验
     *  roleId 非空 必须存在
     *  数组 可空
     * 2. 授权
     *  2.1 第一次授权
     *      直接批量添加即可
     *  2.2 第2+次 授权
     *      如果存在原始授权 此时删除原始权限 添加新的权限记录
     *      如果不存在 直接批量添加即可
     *  合并  2.1 2.2 原来权限不管是否存在 先执行权限记录查询 如果存在 直接删除（根据角色id）
     *  执行批量添加（数组非空 数量>0）
     * @param roleId
     * @param mids
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void addGrant(Integer roleId, Integer[] mids) {
        Role role = this.getById(roleId);
        AssertUtil.isTrue( null == role, "待授权的角色记录不存在！");
        int count = roleMenuService.count(new QueryWrapper<RoleMenu>().eq("role_id",roleId));
        if(count>0){
            AssertUtil.isTrue(!(roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("role_id",roleId))),"角色授权失败！");
        }
        if(null != mids && mids.length>0){
            List<RoleMenu> roleMenus = new ArrayList<RoleMenu>();
            for(Integer mid : mids){
                RoleMenu roleMenu = new RoleMenu();
                roleMenu.setRoleId(roleId);
                roleMenu.setMenuId(mid);
                roleMenus.add(roleMenu);
            }
            AssertUtil.isTrue(!(roleMenuService.saveBatch(roleMenus)),"角色授权失败！");
        }

    }
}
